package org.onionframework.persistence.dao.expression;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.EntityMode;
import org.hibernate.HibernateException;
import org.hibernate.criterion.CriteriaQuery;
import org.hibernate.criterion.SimpleExpression;
import org.hibernate.dialect.function.SQLFunctionRegistry;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.TypedValue;
import org.hibernate.internal.SessionFactoryImpl;
import org.hibernate.type.StandardBasicTypes;
import org.onionframework.core.Onion;
import org.onionframework.persistence.query.DatePart;

public class DatePartExpression extends SimpleExpression {

	private static final long serialVersionUID = -1864118796209879864L;

	private static SQLFunctionRegistry functions = Onion.getBean(SessionFactoryImpl.class).getSqlFunctionRegistry();
	
	private static SessionFactoryImplementor factory = Onion.getBean(SessionFactoryImpl.class);

	private DatePart part;
	private String propertyName;
	private Object value;
	
	protected DatePartExpression(String propertyName, Object value, String op, DatePart datePart) {
		super(propertyName, value, op);
		this.propertyName = propertyName;
		this.value = value;
		this.part = datePart;
	}

	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
	throws HibernateException {

		String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propertyName);
		//Type type = criteriaQuery.getTypeUsingProjection(criteria, propertyName);
		StringBuffer fragment = new StringBuffer();
		
		//SessionFactoryImplementor factory = criteriaQuery.getFactory();
		List<String> args;
		String column;
		args = new ArrayList<String>(1);
		args.add(columns[0]);
		column = functions.findSQLFunction(this.part.name()).render(StandardBasicTypes.INTEGER, args, factory);
		fragment.append( column );
			fragment.append(' ').append( getOp() ).append(' ').append("?");
		return fragment.toString();

	}

	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery)
	throws HibernateException {
		return new TypedValue[]{new TypedValue(StandardBasicTypes.INTEGER,this.value,EntityMode.POJO)};
	}
}
